#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <pthread.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>  
  
#include "../../../include/common/base.h"
  
#include "mqtt_cli.h" 
#include "../../src_comm/my_mqtt.h"

#include "readCfg.h"
 
pid_t  g_pid;

void exit_process( int signo )
{  
	int pid = getpid();
	base::my_printf( "\n msgsvr exit signo=%d pid=%d\n", signo, pid );
	 
	exit(0);
}
 

class CMQTTMsgSvr
{
public:
	CMQTTAsyncPubCli     pubcli; 
	CMQTTAsyncSubCli     subcli; 

public:
	void start()
	{
		char mqttSvrIp[32] = "tcp://127.0.0.1:1883";
 
		pubcli.connect_mqtt(mqttSvrIp);
 
		base::MySleep( 100 );  
		if( subcli.connect_mqtt(SUB_CLIENTID, mqttSvrIp) )
		{ 
			subcli.on_subscribe();
		} 
	} 
	void ReStart()
	{ 
		pubcli.ReStartPubThreasd( ); 
	}

	void check()
	{
		if( subcli.m_bReInitRtdb )
		{  
			subcli.m_bReInitRtdb = false;

			ReStart();
		}
	}
};


void CreateRtdb()
{
	EmptyAll(); 
 

	base::my_printf("CreateRtdb begin.....\n");
 
	CreateRTdb( "SYS_STRING_KEY_NAME",				SYS_STRING_KEY_NO,		SYS_STRING_KEY_COUNT,		sizeof(SYS_STRING_KEY));
	CreateRTdb( "FORE_DEV_TYPE_NAME",				FORE_DEV_TYPE_NO,		FORE_DEV_TYPE_COUNT,		sizeof(FORE_DEV_TYPE)); 
	CreateRTdb( "FORE_DEV_INFO_NAME",				FORE_DEV_INFO_NO,		FORE_DEV_INFO_COUNT,		sizeof(FORE_DEV_DICT));
	CreateRTdb( "FORE_MEA_TEMPLATE_NAME",			FORE_MEA_TEMPLATE_NO,	FORE_MEA_TEMPLATE_COUNT,	sizeof(FORE_MEA_TEMPLATE));
	//CreateRTdb( "FORE_DEV_REG_NAME",				FORE_DEV_REG_NO,		FORE_DEV_REG_COUNT,			sizeof(FORE_DEV_REG));
	CreateRTdb( "FORE_PARAM_CFG_NAME",				FORE_PARAM_CFG_NO,		FORE_PARAM_CFG_COUNT,		sizeof(FORE_PARAM_CFG)); 

	CreateRTdb( "FORE_YX_POINT_RTDB_NAME",			FORE_YX_POINT_NO,		FORE_YX_POINT_COUNT,		sizeof(FORE_YX_POINT));
	CreateRTdb( "FORE_YC_POINT_RTDB_NAME",			FORE_YC_POINT_NO,		FORE_YC_POINT_COUNT,		sizeof(FORE_YC_POINT)); 
	CreateRTdb( "FORE_YK_NO_NAME",					FORE_YK_NO,				FORE_YK_COUNT,				sizeof(FORE_YK));
 	//CreateRTdb( "FORE_SUBSCRIBE_NAME",				FORE_SUBSCRIBE_NO,		FORE_SUBSCRIBE_COUNT,		sizeof(FORE_SUBSCRIBE));
 	
	//CreateRTdb( "FORE_APP_SUBSCRIBE_REG_NAME",		FORE_APP_SUBSCRIBE_REG_NO,	FORE_APP_SUBSCRIBE_REG_COUNT,	sizeof(FORE_APP_SUBSCRIBE_REG));

	CreateRTdb( "FORE_EVENT_POINT_NAME",		FORE_EVENT_POINT_NO,	FORE_EVENT_POINT_COUNT,	sizeof(FORE_EVENT_POINT ));

	CreateRTdb( "FORE_CURVE_NAME",		FORE_CURVE_NO,	FORE_CURVE_COUNT,	sizeof(RTDB_YC_CURVE_5MIN));
	 	
	base::my_printf("CreateRtdb end.....\n");
}
 
 bool load_rtdb()
{
	if(  !base::is_exist_file("/rtdbms/LIB0002.data") ) { 
 
		if( !OpenDbms() ) {
			printf("msgSvr: open rtdbms error! \n"); 
			printf("rm -rf /rtdbms \n"); 
			system("rm -rf /rtdbms");
			return false;
		}
		else{
			printf("open rtdbms sucess!\n"); 
		}  
 
		void CreateRtdb();
		CreateRtdb(); 

		if( !TDbFun::set_rtdb_version(CURRENT_RTDB_VERSION) )
			printf("set_rtdb_version false !\n"); 

		SaveRtdb();
		
		base::my_printf("Load rtdb rtdbms\n");

		return true;
	} 
	else {  
		if( !OpenDbms() ) {
			base::my_printf("msgSvr: open rtdbms error! \n");  
			printf("rm -rf /rtdbms \n"); 
			system("rm -rf /rtdbms");
			return false;
		}
		else{
			base::my_printf("open rtdbms sucess!\n"); 
		}

		unsigned int ver = TDbFun::get_rtdb_Version();
		
		if( ver != CURRENT_RTDB_VERSION ) 
		{
			printf("rtdb ver[%d] != cur rtdb version[%d]!\n", ver, CURRENT_RTDB_VERSION ); 

			printf("rm -rf /rtdbms \n");
			system("rm -rf /rtdbms");

			return false;
		} 

		if( !LoadRtdb() ) 
		{
			base::my_printf(" Load rtdb rtdbms failed2! \n"); 
			return false;
		}
		else
		{
			base::my_printf(" Load rtdb rtdbms sucess2! \n"); 
		} 

		return true;
	}

}


unsigned char g_cur_jc_poweroffAlm;
void check_jc_status()
{ 
	std::vector<FORE_DEV_DICT>   aryDev;
	TDbFun::GetDevs_ByDevType( "JC", aryDev ); 
	
	base::my_printf("JC=%d \n ", aryDev.size());
	for( int i=0; i<aryDev.size(); i++ )
	{
		FORE_DEV_DICT & dev = aryDev[i];

		char chrKey[64] ={0};
		sprintf(chrKey, "%s:%s", dev.dev_nodeID, "PwrOffAlm");  
		FORE_YX_POINT * pYx = (FORE_YX_POINT*)FindRec_stringkey(FORE_YX_POINT_NO, chrKey );
		if( pYx ) {
			if( g_cur_jc_poweroffAlm == 2 ) {
				g_cur_jc_poweroffAlm = pYx->CurYxRTVal;
				//base::my_printf("  g_cur_jc_poweroffAlm == 2 \n");
			}
			else {
				//base::my_printf("  g_cur_jc_poweroffAlm == CurYxRTVal \n");
				if( g_cur_jc_poweroffAlm != pYx->CurYxRTVal && pYx->CurYxRTVal != pYx->PreYxRTVal ) {
					g_cur_jc_poweroffAlm = pYx->CurYxRTVal;
					SaveRtdb();
					printf(" JC:PwrOffAlm changed -->> rtdbms to save !\n"); 
					break;
				}
			}	 
		}
	}

}


bool MY_PRINTF_TAG  = 0;
int main(int argc, char* argv[])
{
	signal(SIGKILL , exit_process);
	signal(SIGINT  , exit_process);
	signal(SIGTERM , exit_process);	 
	signal(SIGQUIT , exit_process);	 
	 
	if( argc == 2 ) { 
		if( strcmp(argv[1], "p") == 0 )
			MY_PRINTF_TAG = 1 ; 
	} 
	
	g_pid = getpid();
	 
	base::MySleep(1000);

	printf( "\n msgsvr run successfully! pid =%d \n ", g_pid ); 
	  
	if( !load_rtdb() ) {
		base::MySleep(2000); 
		printf( " msgSvr exit \n " ); 
		exit(0);
	}
	
	base::MySleep(1000);
  
 
	CReadCfg   cfg;
	cfg.process_rtdb();
	
	CMQTTMsgSvr   mqtt_svr;
	mqtt_svr.start();
 
 
	unsigned int  loop_count = 1;
	while(1)
	{
		if( (loop_count % 60*60) == 0  )   //1h
		{
			SaveRtdb();
			printf(" auto SaveRtdb sucess! \n");
		}
		
		if( (loop_count % 4) == 0  ) 
		{ 
			//check_jc_status();
		}

		mqtt_svr.check();

		if( loop_count % (2* 60) == 0 ) {
			cfg.process_rtdb();
		}
	
		loop_count++;

		base::MySleep(1000);
	}
	
	return 0;
}
 
  
